<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CronGo - 定时任务管理系统</title>
    <link rel="stylesheet" href="/static/css/bootstrap.min.css">
    <script src="/static/js/jquery.min.js"></script>
    <script src="/static/js/bootstrap.min.js"></script>
    <style>
        .log-success { color: #00ff00; }
        .log-error { color: #ff4444; }
        .log-output { 
            font-family: monospace;
            white-space: pre-wrap;
            background-color: #1e1e1e;
            color: #ffffff;
            padding: 10px;
            border-radius: 4px;
            margin: 5px 0;
        }
        #logList {
            height: 500px;
            overflow-y: auto;
            background-color: #1e1e1e;
            color: #ffffff;
            padding: 15px;
            border-radius: 6px;
        }
        .list-group-item {
            background-color: #2d2d2d;
            border-color: #3d3d3d;
            margin-bottom: 8px;
            color: #ffffff;
        }
        .list-group-item small {
            color: #888888;
        }
        .modal-lg {
            max-width: 900px;
        }
        .log-timestamp {
            color: #888888;
        }
        .log-duration {
            color: #888888;
            font-size: 0.9em;
        }
        /* 添加 bootstrap-icons 的替代样式 */
        .bi-box-arrow-up-right::before {
            content: "↗";
            font-style: normal;
            font-weight: bold;
            margin-right: 4px;
        }
    </style>
</head>
<body>
    <div class="container mt-4">
        <h1>CronGo 定时任务管理系统</h1>
        
        <!-- 分组过滤 -->
        <div class="row mt-4">
            <div class="col">
                <div class="btn-group" role="group" id="taskGroups">
                    <button type="button" class="btn btn-outline-primary active" onclick="filterByGroup('')">全部</button>
                    <!-- 分组按钮将通过JavaScript动态加载 -->
                </div>
            </div>
        </div>

        <!-- 任务列表 -->
        <div class="card mt-4">
            <div class="card-header d-flex justify-content-between align-items-center">
                <h5 class="mb-0">任务列表</h5>
                <button class="btn btn-primary" onclick="showCreateTaskModal()">
                    添加任务
                </button>
            </div>
            <div class="card-body">
                <table class="table">
                    <thead>
                        <tr>
                            <th>ID</th>
                            <th>名称</th>
                            <th>分组</th>
                            <th>Cron表达式</th>
                            <th>命令</th>
                            <th>最近运行时间</th>
                            <th>状态</th>
                            <th>操作</th>
                        </tr>
                    </thead>
                    <tbody id="taskList">
                        <!-- 任务列表将通过JavaScript动态加载 -->
                    </tbody>
                </table>
            </div>
        </div>

        <!-- 任务表单模态框 -->
        <div class="modal fade" id="taskModal" tabindex="-1">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title" id="taskModalTitle">任务信息</h5>
                        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                    </div>
                    <div class="modal-body">
                        <form id="taskForm">
                            <input type="hidden" id="taskId">
                            <div class="mb-3">
                                <label class="form-label">任务名称</label>
                                <input type="text" class="form-control" id="taskName" required>
                            </div>
                            <div class="mb-3">
                                <label class="form-label">分组</label>
                                <input type="text" class="form-control" id="groupName" value="default">
                            </div>
                            <div class="mb-3">
                                <label class="form-label">Cron表达式</label>
                                <input type="text" class="form-control" id="cronExpr" required>
                                <div class="form-text">示例：*/5 * * * *（每5分钟执行一次）或 0 */1 * * * *（每小时执行一次）</div>
                            </div>
                            <div class="mb-3">
                                <label class="form-label">执行命令</label>
                                <input type="text" class="form-control" id="command" required>
                            </div>
                            <div class="mb-3">
                                <label class="form-label">描述</label>
                                <textarea class="form-control" id="description"></textarea>
                            </div>
                            <div class="mb-3">
                                <label class="form-label">状态</label>
                                <select class="form-control" id="status">
                                    <option value="1">启用</option>
                                    <option value="2">禁用</option>
                                </select>
                            </div>
                        </form>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
                        <button type="button" class="btn btn-primary" onclick="saveTask()">保存</button>
                    </div>
                </div>
            </div>
        </div>

        <!-- 日志查看模态框 -->
        <div class="modal fade" id="logModal" tabindex="-1">
            <div class="modal-dialog modal-lg">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title">执行日志</h5>
                        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                    </div>
                    <div class="modal-body p-3">
                        <div id="logList" class="list-group">
                            <!-- 日志内容将通过JavaScript动态加载 -->
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- 任务运行记录抽屉（使用右侧模态框替代） -->
        <div class="modal fade" id="taskLogsDrawer" tabindex="-1">
            <div class="modal-dialog modal-lg" style="position: fixed; right: 0; margin-right: 0; height: 100%; margin-top: 0;">
                <div class="modal-content" style="height: 100vh;">
                    <div class="modal-header">
                        <h5 class="modal-title">运行记录</h5>
                        <div>
                            <button type="button" class="btn btn-sm btn-primary me-2" onclick="openLogsInNewWindow()">
                                ↗ 新窗口打开
                            </button>
                            <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                        </div>
                    </div>
                    <div class="modal-body" style="overflow-y: auto;">
                        <div class="table-responsive">
                            <table class="table table-striped">
                                <thead>
                                    <tr>
                                        <th>ID</th>
                                        <th>开始时间</th>
                                        <th>结束时间</th>
                                        <th>执行时长</th>
                                        <th>状态</th>
                                    </tr>
                                </thead>
                                <tbody id="drawerLogList">
                                    <!-- 日志列表将通过JavaScript动态加载 -->
                                </tbody>
                            </table>
                        </div>
                        <div id="drawerLoadMore" class="text-center mt-3" style="display: none;">
                            <button class="btn btn-primary btn-sm" onclick="loadMoreDrawerLogs()">加载更多</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script>
        // 格式化执行时长
        function formatDuration(seconds) {
            if (seconds < 0.1) return "< 0.1秒";
            
            const days = Math.floor(seconds / (24 * 3600));
            seconds %= (24 * 3600);
            const hours = Math.floor(seconds / 3600);
            seconds %= 3600;
            const minutes = Math.floor(seconds / 60);
            seconds %= 60;
            
            let result = [];
            if (days > 0) result.push(days + "天");
            if (hours > 0) result.push(hours + "小时");
            if (minutes > 0) result.push(minutes + "分");
            if (seconds > 0) result.push(seconds.toFixed(1) + "秒");
            
            return result.join(" ");
        }

        // 检查登录状态
        function checkAuth() {
            const token = localStorage.getItem('token');
            if (!token) {
                window.location.href = '/login';
                return;
            }
        }

        // 添加认证头
        function addAuthHeader(xhr) {
            const token = localStorage.getItem('token');
            if (token) {
                xhr.setRequestHeader('Authorization', 'Bearer ' + token);
            }
        }

        // 处理认证错误
        function handleAuthError(xhr) {
            if (xhr.status === 401) {
                localStorage.removeItem('token');
                window.location.href = '/login';
            }
        }

        // 页面加载完成后初始化
        $(document).ready(function() {
            // 检查登录状态
            checkAuth();

            // 设置全局AJAX配置
            $.ajaxSetup({
                beforeSend: function(xhr) {
                    addAuthHeader(xhr);
                },
                error: function(xhr) {
                    handleAuthError(xhr);
                }
            });

            loadTaskGroups();
            loadTasks();
        });

        // 加载任务组
        function loadTaskGroups() {
            $.ajax({
                url: '/api/task-groups',
                method: 'GET',
                success: function(groups) {
                    let html = '<button type="button" class="btn btn-outline-primary active" onclick="filterByGroup(\'\')">全部</button>';
                    groups.forEach(group => {
                        html += `
                            <button type="button" class="btn btn-outline-primary" 
                                    onclick="filterByGroup('${group}')">${group}</button>
                        `;
                    });
                    $('#taskGroups').html(html);
                }
            });
        }

        // 切换任务状态
        function toggleTaskStatus(taskId, enabled) {
            const task = {
                status: enabled ? 1 : 2
            };
            
            $.ajax({
                url: `/api/tasks/${taskId}`,
                method: 'PUT',
                contentType: 'application/json',
                data: JSON.stringify(task),
                success: function() {
                    loadTasks();
                },
                error: function(xhr) {
                    alert('更新状态失败: ' + (xhr.responseJSON?.error || '未知错误'));
                    // 恢复复选框状态
                    $(`#taskList tr[data-id="${taskId}"] .form-check-input`).prop('checked', !enabled);
                }
            });
        }

        // 加载任务列表
        function loadTasks() {
            $.ajax({
                url: '/api/tasks',
                method: 'GET',
                success: function(tasks) {
                    let html = '';
                    tasks.forEach(task => {
                        html += `
                            <tr data-group="${task.group_name || ''}" data-id="${task.id}">
                                <td>${task.id}</td>
                                <td>${task.name}</td>
                                <td>${task.group_name || '-'}</td>
                                <td>${task.cron_expr}</td>
                                <td>${task.command}</td>
                                <td>${task.last_run_time ? new Date(task.last_run_time).toLocaleString() : '-'}</td>
                                <td>
                                    <div class="form-check form-switch">
                                        <input class="form-check-input" type="checkbox" 
                                            ${task.status === 1 ? 'checked' : ''} 
                                            onchange="toggleTaskStatus(${task.id}, this.checked)">
                                    </div>
                                </td>
                                <td>
                                    <button class="btn btn-sm btn-primary me-1" onclick="viewTaskLogs(${task.id})">
                                        运行记录
                                    </button>
                                    <button class="btn btn-sm btn-info me-1" onclick="viewTaskOutput(${task.id})">
                                        查看输出
                                    </button>
                                    <button class="btn btn-sm btn-warning me-1" onclick="editTask(${task.id})">
                                        编辑
                                    </button>
                                    <button class="btn btn-sm btn-danger" onclick="deleteTask(${task.id})">
                                        删除
                                    </button>
                                </td>
                            </tr>
                        `;
                    });
                    $('#taskList').html(html);
                }
            });
        }

        // 分组过滤
        function filterByGroup(group) {
            $('#taskGroups button').removeClass('active');
            $(`#taskGroups button:contains('${group || '全部'}')`).addClass('active');
            if (!group) {
                $('#taskList tr').show();
            } else {
                $('#taskList tr').hide();
                $(`#taskList tr[data-group="${group}"]`).show();
            }
        }

        // 显示创建任务模态框
        function showCreateTaskModal() {
            $('#taskForm')[0].reset();
            $('#taskId').val('');
            $('#taskModalTitle').text('新建任务');
            new bootstrap.Modal('#taskModal').show();
        }

        // 查看任务输出
        function viewTaskOutput(taskId) {
            // 先清空日志内容
            $('#logList').html('<div class="text-center">正在加载日志...</div>');
            new bootstrap.Modal('#logModal').show();
            
            $.ajax({
                url: `/api/tasks/${taskId}/output`,
                method: 'GET',
                success: function(content) {
                    if (!content) {
                        $('#logList').html('<div class="text-center">暂无输出</div>');
                        return;
                    }
                    
                    // 将日志内容按行分割并只保留最后100行
                    const lines = content.split('\n');
                    const lastLines = lines.slice(-100).join('\n');
                    
                    $('#logList').html(`
                        <div class="text-muted small mb-2">显示最近100行输出</div>
                        <pre class="log-output" style="max-height: 500px; overflow-y: auto; background-color: #1e1e1e; color: #ffffff; padding: 10px; border-radius: 4px;">${lastLines || '暂无输出'}</pre>
                    `);

                    // 自动滚动到最后一行
                    const logOutput = $('#logList .log-output');
                    logOutput.scrollTop(logOutput[0].scrollHeight);
                },
                error: function() {
                    $('#logList').html('<div class="text-center text-danger">加载输出失败</div>');
                }
            });
        }

        // 编辑任务
        function editTask(id) {
            $.get(`/api/tasks/${id}`, function(task) {
                $('#taskId').val(task.id);
                $('#taskName').val(task.name);
                $('#groupName').val(task.group_name);
                $('#cronExpr').val(task.cron_expr);
                $('#command').val(task.command);
                $('#description').val(task.description);
                $('#status').val(task.status);
                $('#taskModalTitle').text('编辑任务');
                new bootstrap.Modal('#taskModal').show();
            });
        }

        // 保存任务
        function saveTask() {
            const taskId = $('#taskId').val();
            const task = {
                name: $('#taskName').val(),
                group_name: $('#groupName').val(),
                cron_expr: $('#cronExpr').val(),
                command: $('#command').val(),
                description: $('#description').val(),
                status: parseInt($('#status').val())
            };

            const url = taskId ? `/api/tasks/${taskId}` : '/api/tasks';
            const method = taskId ? 'PUT' : 'POST';

            $.ajax({
                url: url,
                method: method,
                contentType: 'application/json',
                data: JSON.stringify(task),
                success: function() {
                    new bootstrap.Modal('#taskModal').hide();
                    loadTasks();
                    loadTaskGroups();
                },
                error: function(xhr) {
                    alert('保存失败: ' + (xhr.responseJSON?.error || '未知错误'));
                }
            });
        }

        // 删除任务
        function deleteTask(id) {
            if (confirm('确定要删除这个任务吗？')) {
                $.ajax({
                    url: `/api/tasks/${id}`,
                    method: 'DELETE',
                    success: function() {
                        loadTasks();
                        loadTaskGroups();
                    },
                    error: function(xhr) {
                        alert('删除失败: ' + (xhr.responseJSON?.error || '未知错误'));
                    }
                });
            }
        }

        let currentTaskId = null;
        let lastDrawerLogId = 0;
        const drawerPageSize = 20;

        // 查看运行记录（模态框式）
        function viewTaskLogs(taskId) {
            currentTaskId = taskId;
            lastDrawerLogId = 0;
            $('#drawerLogList').empty();
            $('#drawerLoadMore').hide();
            
            // 显示模态框
            new bootstrap.Modal('#taskLogsDrawer').show();
            
            // 加载日志
            loadDrawerLogs();
        }

        // 加载抽屉中的日志
        function loadDrawerLogs() {
            $.ajax({
                url: `/api/tasks/${currentTaskId}/task-logs?last_id=${lastDrawerLogId}&limit=${drawerPageSize}`,
                method: 'GET',
                success: function(logs) {
                    if (!logs || logs.length === 0) {
                        if (lastDrawerLogId === 0) {
                            $('#drawerLogList').html('<tr><td colspan="5" class="text-center">暂无运行记录</td></tr>');
                        }
                        $('#drawerLoadMore').hide();
                        return;
                    }
                    
                    let html = '';
                    logs.forEach(log => {
                        lastDrawerLogId = log.id;
                        const duration = log.end_time ? 
                            (new Date(log.end_time) - new Date(log.start_time)) / 1000 :
                            null;
                        
                        html += `
                            <tr>
                                <td>${log.id}</td>
                                <td>${new Date(log.start_time).toLocaleString()}</td>
                                <td>${log.end_time ? new Date(log.end_time).toLocaleString() : '-'}</td>
                                <td class="duration">${duration ? formatDuration(duration) : '-'}</td>
                                <td>
                                    <span class="badge ${log.success ? 'bg-success' : 'bg-danger'}">
                                        ${log.success ? '成功' : '失败'}
                                    </span>
                                </td>
                            </tr>
                        `;
                    });
                    
                    if (lastDrawerLogId === 0) {
                        $('#drawerLogList').html(html);
                    } else {
                        $('#drawerLogList').append(html);
                    }
                    
                    // 如果返回的记录数等于页大小，说明可能还有更多记录
                    $('#drawerLoadMore').toggle(logs.length === drawerPageSize);
                },
                error: function(xhr) {
                    if (lastDrawerLogId === 0) {
                        $('#drawerLogList').html('<tr><td colspan="5" class="text-center text-danger">加载失败: ' + (xhr.responseJSON?.error || '未知错误') + '</td></tr>');
                    }
                    $('#drawerLoadMore').hide();
                }
            });
        }

        // 加载更多抽屉中的日志
        function loadMoreDrawerLogs() {
            loadDrawerLogs();
        }

        // 在新窗口打开运行记录
        function openLogsInNewWindow() {
            window.open(`/task-logs?id=${currentTaskId}`, '_blank');
        }
    </script>
</body>
</html> 
